package org.lex.notepad.ui;

import java.awt.Component;
import java.awt.Container;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;

import org.lex.app.prefs.ResourceMap;
import org.lex.notepad.Notepad;
import org.lex.notepad.util.CK;


public class DropHandler extends DropTargetAdapter {
	private Notepad notepad = null;
	private ResourceMap rm = null;

	public static void registerDropHandler(Container root) {
		new DropHandler(root);
	}

	private DropHandler(Container root) {
		this.notepad = Notepad.getApplication();
		this.rm = notepad.getContext().getResourceManager().getResourceMap();
		this.installDropHandler(root);
	}

	private void installDropHandler(Container root) {
		root.setDropTarget(new DropTarget(root, this));
		// =================================================
		Stack<Container> stack = new Stack<Container>();
		stack.push(root);
		while (false == stack.empty()) {
			Component[] children = stack.pop().getComponents();
			if (null == children)
				continue;
			for (Component c : children) {
				c.setDropTarget(new DropTarget(c, this));
				if (c instanceof Container)
					stack.push((Container) c);
			}
		}
	}

	public void drop(DropTargetDropEvent e) {
		if (false == handleFileListDrop(e))
			e.rejectDrop();
	}

	@SuppressWarnings("unchecked")
	public boolean handleFileListDrop(DropTargetDropEvent event) {
		boolean hasFile = false;
		event.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE | DnDConstants.ACTION_LINK);
		Transferable trans = event.getTransferable();
		DataFlavor[] flavors = trans.getTransferDataFlavors();
		if (null == flavors || 0 == flavors.length)
			return hasFile;
		for (DataFlavor data : flavors) {
			if (data.isFlavorJavaFileListType()) {
				hasFile = true;
				try {
					handleFileList((List<File>) trans.getTransferData(data));
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		event.dropComplete(true);
		return hasFile;
	}

	private void handleFileList(List<File> files) {
		if (null == files || 0 == files.size())
			return;
		Charset charset = null;
		try {
			String charsetName = rm.getString(CK.EDITOR_ENCODING);
			if (null != charsetName && false == charsetName.isEmpty())
				charset = Charset.forName(charsetName);
		} catch (Exception e) {
			charset = Charset.defaultCharset();
		}
		for (Iterator<File> iter = files.iterator(); iter.hasNext();) {
			File file = iter.next();
			if (null == file || false == file.exists() || false == file.isFile())
				continue;
			notepad.getNotepadActions().openFile(file, charset);
		}
	}
}
